﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LotteryVote.Entity;
using LotteryVote.Data;
using LotteryVote.Logic.Exceptions;
using LotteryVote.Utility;
using System.Data.SqlClient;
using LotteryVote.Logic.Member;
using System.Web;

namespace LotteryVote.Logic
{
    public class UserFacade
    {
        #region Properties
        private UserDataAccess _daUser;
        private UserInfoDataAccess _daUserInfo;
        private LoginLogDataAccess _daLoginLog;

        internal UserDataAccess DaUser
        {
            get
            {
                if (_daUser == null)
                    _daUser = new UserDataAccess();
                return _daUser;
            }
            set
            {
                _daUser = value;
            }
        }
        internal UserInfoDataAccess DaUserInfo
        {
            get
            {
                if (_daUserInfo == null)
                    _daUserInfo = new UserInfoDataAccess();
                return _daUserInfo;
            }
            set
            {
                _daUserInfo = value;
            }
        }
        internal LoginLogDataAccess DaLoginLog
        {
            get
            {
                if (_daLoginLog == null)
                    _daLoginLog = new LoginLogDataAccess();
                return _daLoginLog;
            }
            set
            {
                _daLoginLog = value;
            }
        }
        private UserCommissionFacade _userCommFacade;

        internal UserCommissionFacade UserCommissionFacade
        {
            get
            {
                if (_userCommFacade == null)
                    _userCommFacade = new UserCommissionFacade();
                return _userCommFacade;
            }
            set
            {
                _userCommFacade = value;
            }
        }
        #endregion
        #region Select
        public User GetUser(int userId)
        {
            return DaUser.GetUserById(userId);
        }
        public IList<LoginLog> ListUserLoginLog(User user)
        {
            return DaLoginLog.ListTopLog(user, 100);
        }
        /// <summary>
        /// 获取所有用户
        /// </summary>
        /// <param name="loadCommission">if set to <c>true</c> [load commission].</param>
        /// <returns></returns>
        public IList<User> GetAllUser(bool loadCommission = false)
        {
            return LoadUserCommission(DaUser.GetAllUser(), loadCommission);
        }
        public IList<User> GetCompanyUser(bool loadCommission = false)
        {
            return LoadUserCommission(DaUser.GetUserByRole(SystemRole.Company), loadCommission);
        }
        /// <summary>
        ///获取Super用户.
        /// </summary>
        /// <param name="loadCommission">是否加载用户的佣金信息.</param>
        /// <returns></returns>
        public IList<User> GetSuperUser(bool loadCommission = false)
        {
            return LoadUserCommission(DaUser.GetUserByRole(SystemRole.Super), loadCommission);
        }
        public IList<User> FindSuperUser(string name, string userName, UserState state, SystemRole role, string sortField)
        {
            return DaUser.ListUserByCondition(name, userName, state, role, sortField);
        }
        /// <summary>
        /// 获取所有Master角色的用户
        /// </summary>
        /// <param name="loadCommission">if set to <c>true</c> [load commission].</param>
        /// <returns></returns>
        public IList<User> GetMasterUser(bool loadCommission = false)
        {
            return LoadUserCommission(DaUser.GetUserByRole(SystemRole.Master), loadCommission);
        }
        /// <summary>
        /// 获取指定用户的子用户（角色为Master）
        /// </summary>
        /// <param name="user">The user.</param>
        /// <param name="loadCommission">if set to <c>true</c> [load commission].</param>
        /// <returns></returns>
        public IList<User> GetMasterUser(User user, bool loadCommission = false)
        {
            return LoadUserCommission(GetUsers(user, SystemRole.Master), loadCommission);
        }
        /// <summary>
        /// 获取所有Agent角色的用户.
        /// </summary>
        /// <param name="loadCommission">if set to <c>true</c> [load commission].</param>
        /// <returns></returns>
        public IList<User> GetAgentUser(bool loadCommission = false)
        {
            return LoadUserCommission(DaUser.GetUserByRole(SystemRole.Agent), loadCommission);
        }
        /// <summary>
        /// 获取指定用户的子用户（角色为Agent）.
        /// </summary>
        /// <param name="user">The user.</param>
        /// <param name="loadCommission">if set to <c>true</c> [load commission].</param>
        /// <returns></returns>
        public IList<User> GetAgentUser(User user, bool loadCommission = false)
        {
            return LoadUserCommission(GetUsers(user, SystemRole.Agent), loadCommission);
        }
        public IList<User> GetGuestUser(User user, bool loadCommission = false)
        {
            return LoadUserCommission(GetUsers(user, SystemRole.Guest), loadCommission);
        }
        /// <summary>
        /// 获取所有角色为Guest的用户.
        /// </summary>
        /// <param name="loadCommission">if set to <c>true</c> [load commission].</param>
        /// <returns></returns>
        public IList<User> GetGuestUser(bool loadCommission = false)
        {
            return LoadUserCommission(DaUser.GetUserByRole(SystemRole.Guest), loadCommission);
        }
        /// <summary>
        /// 获取指定用户宗族用户（父级用户树，包括该用户本身）
        /// </summary>
        /// <param name="userId">The user id.</param>
        /// <param name="loadCommission">if set to <c>true</c> [load commission].</param>
        /// <returns></returns>
        public IList<User> GetUserFamily(int userId, bool loadCommission = false)
        {
            User user = DaUser.GetUserById(userId);
            if (user == null)
                throw new InvalidDataException("User,userId:" + userId);
            return LoadUserCommission(DaUser.GetParentUser(user), loadCommission);
        }
        public IList<User> GetChildUsers(User user, bool loadCommission = false)
        {
            if (user == null)
                throw new ArgumentNullException("User");
            return LoadUserCommission(DaUser.GetChild(user), loadCommission);
        }
        internal IList<User> GetParentUser(User user)
        {
            var parentUser = HttpContext.Current.Session[user.UserName] as IList<User>;
            if (parentUser == null)
            {
                parentUser = DaUser.GetParentUser(user);
                HttpContext.Current.Session[user.UserName] = parentUser;
            }
            return parentUser;
        }
        private IList<User> GetUsers(User user, SystemRole role, bool loadCommission = false)
        {
            return LoadUserCommission(DaUser.GetDescendantByRole(user, role), loadCommission);
        }
        /// <summary>
        /// 用户佣金加载.
        /// </summary>
        /// <param name="userList">用户列表.</param>
        /// <param name="loadCommission">是否加载用户的佣金设置.</param>
        /// <returns></returns>
        private IList<User> LoadUserCommission(IList<User> userList, bool loadCommission)
        {
            if (loadCommission)
                userList.ForEach((it) =>
                {
                    it.LoadUserCommission(() =>
                    {
                        return UserCommissionFacade.DaUserComm.GetUserCommission(it);
                    });
                });
            return userList;
        }
        #endregion

        public void UpdatePassword(User user, string password)
        {
            user.UserInfo.Password = EncryptHelper.Encrypt(password);
            DaUserInfo.Update(user.UserInfo);
        }
        public void UpdateUser(User user, decimal givenCredit, double shareRate, UserState state)
        {
            var childUser = GetChildUsers(user);
            var largestShareChild = childUser.OrderByDescending(it => it.UserInfo.ShareRate).FirstOrDefault();
            if (largestShareChild != null)
            {
                if (shareRate < largestShareChild.UserInfo.ShareRate)
                    throw new PromptException("分成必须大于{0}", largestShareChild.UserInfo.ShareRate * 100);
            }
            user.UserInfo.ShareRate = shareRate;
            var parent = GetUser(user.ParentId);
            if (givenCredit > user.UserInfo.GivenCredit)
            {
                decimal diff = givenCredit - user.UserInfo.GivenCredit;
                if (parent.UserInfo.AvailableGivenCredit < diff)
                    throw new PromptException("信用额必须小于{0}", user.UserInfo.GivenCredit + parent.UserInfo.AvailableGivenCredit);
                parent.UserInfo.AvailableGivenCredit -= diff;
                var userUseCredit = user.UserInfo.GivenCredit - user.UserInfo.AvailableGivenCredit;
                user.UserInfo.GivenCredit = givenCredit;
                user.UserInfo.AvailableGivenCredit = givenCredit - userUseCredit;
            }
            else if (givenCredit < user.UserInfo.GivenCredit)
            {
                //已用信用额
                decimal userUsedCredit = user.UserInfo.GivenCredit - user.UserInfo.AvailableGivenCredit;
                if (givenCredit < userUsedCredit)
                    throw new PromptException("信用额必须大于{0}", userUsedCredit);
                decimal diff = user.UserInfo.GivenCredit - givenCredit;
                parent.UserInfo.AvailableGivenCredit += diff;

                user.UserInfo.GivenCredit = givenCredit;
                user.UserInfo.AvailableGivenCredit -= diff;
            }
            user.UserInfo.State = state;
            DaUserInfo.ExecuteWithTransaction(() =>
            {
                DaUserInfo.Update(user.UserInfo);
                DaUserInfo.Update(parent.UserInfo);
            });
        }
        public void DeleteUser(int userId)
        {
            var user = GetUser(userId);
            if (user == null || user.Role == SystemRole.Company) return;    //公司级别用户不能直接删除
            var childUsers = DaUser.GetDescendantUser(user).OrderByDescending(it => it.UserId);
            DaUser.ExecuteWithTransaction(() =>
            {
                foreach (var childUser in childUsers)
                {
                    DaUser.Delete(childUser);
                }
                var parent = GetUser(user.ParentId);
                parent.UserInfo.AvailableGivenCredit += user.UserInfo.GivenCredit;
                DaUserInfo.Tandem(DaUser);
                DaUserInfo.Update(parent.UserInfo);
            });
        }

        /// <summary>
        /// 添加超级代理.
        /// </summary>
        /// <param name="user">用户基本信息.</param>
        /// <param name="shareRate">公司需要分成数（百分数，例如：20）.</param>
        /// <param name="leastRate">超级代理设置最小分成数（百分数，例如:20）.</param>
        /// <param name="largestRate">超级代理设置最大分成数（百分数，例如80）</param>
        public void AddSuper(User user, params int[] species)
        {
            var userStrategy = UserStrategyFactory.GetFactory().GetUserStrategy(SystemRole.Super);
            userStrategy.AddParam(UserStrategy.ROLE, SystemRole.Super);
            userStrategy.AddParam(UserStrategy.SPECIES, species);
            userStrategy.AddUser(user);
        }
        public void AddMaster(User user, params int[] species)
        {
            var userStrategy = UserStrategyFactory.GetFactory().GetUserStrategy(SystemRole.Master);
            userStrategy.AddParam(UserStrategy.ROLE, SystemRole.Master);
            userStrategy.AddParam(UserStrategy.SPECIES, species);
            userStrategy.AddUser(user);
        }
        public void AddAgent(User user, params int[] species)
        {
            var userStrategy = UserStrategyFactory.GetFactory().GetUserStrategy(SystemRole.Agent);
            userStrategy.AddParam(UserStrategy.ROLE, SystemRole.Agent);
            userStrategy.AddParam(UserStrategy.SPECIES, species);
            userStrategy.AddUser(user);
        }
        public void AddGuest(User user, int[] groups, params int[] species)
        {
            var userStrategy = UserStrategyFactory.GetFactory().GetUserStrategy(SystemRole.Guest);
            userStrategy.AddParam(UserStrategy.ROLE, SystemRole.Guest);
            userStrategy.AddParam(UserStrategy.SPECIES, species);
            userStrategy.AddParam(UserStrategy.GROUPIDS, groups);
            userStrategy.AddUser(user);
        }

        /// <summary>
        /// 创建新用户(主要用户用户创建)
        /// </summary>
        /// <param name="parentId">上一级用户，如为Company用户则Parent为null.</param>
        /// <param name="userName">用户名.</param>
        /// <param name="password">用户密码.</param>
        /// <param name="name">名字.</param>
        /// <param name="givenCredit">信用额.</param>
        /// <param name="userState">用户状态.</param>
        /// <param name="email">邮件.</param>
        /// <returns></returns>
        public static User BuildNewUser(int parentId, string userName, string password, string name,
            decimal givenCredit, double shareRate, UserState userState, string email)
        {
            User user = new User
            {
                UserName = userName,
                UserInfo = new UserInfo
                {
                    Password = password,
                    Name = name,
                    GivenCredit = givenCredit < 0 ? Math.Abs(givenCredit) : givenCredit,
                    State = userState,
                    ShareRate = shareRate < 0 ? Math.Abs(shareRate) : shareRate,
                    Email = email
                }
            };
            if (parentId > 0)
                user.ParentId = parentId;
            return user;
        }
    }
}
